package com.ibeeking.found.report.rest.config;

import com.alibaba.fastjson.JSONObject;
import com.ibeeking.found.common.constants.HeaderNounConstant;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.report.service.common.constant.ReportConstant;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.nimbusds.jose.JWSObject;
import org.apache.logging.log4j.util.Strings;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.Objects;


/**
 * {@link JmReportTokenServiceI} 实现类，提供积木报表的 Token 校验、用户信息的查询等功能
 /**
 * Created by ibeeking on 2021/3/24.
 */
@Component
@ComponentScan(basePackages = "org.jeecg.modules.jmreport") // 扫描积木报表的包
public class JmReportTokenConfig implements JmReportTokenServiceI {
    /**
     * 自定义 API 数据集appian自定义 Header，解决 Token 传递。
     * 参考 <a href="http://report.jeecg.com/2222224">api数据集token机制详解</a> 文档
     *
     * @return 新 head
     */
    @Override
    public HttpHeaders customApiHeader() {
        String token = getToken();
        HttpHeaders header = new HttpHeaders();
        header.add(ReportConstant.JM_TOKEN_KEY, token);
        header.add(HeaderNounConstant.AUTHORIZATION, token);
        header.add(ReportConstant.JM_TOKEN, token);
        return header;
    }

    /**
     * 校验 Token 是否有效，即验证通过
     *
     * @param token JmReport 前端传递的 token
     * @return 是否认证通过
     */
    @Override
    public Boolean verifyToken(String token) {
        try {
            if (StringUtils.isEmpty(token)) return false;
            JSONObject tokenObject = parseToken(token);
            String userId = tokenObject.get(HeaderNounConstant.USER_ID).toString();
            if(StringUtils.isEmpty(userId)) return false;
            return true;
        }catch(Exception ex) {
            return false;
        }
    }

    /**
     * 获得用户编号
     * <p>
     * 虽然方法名获得的是 username，实际对应到项目中是用户编号
     *
     * @param token JmReport 前端传递的 token
     * @return 用户编号
     */
    @Override
    public String getUsername(String token) {
        try {
            if (StringUtils.isEmpty(token)) return "";
            JSONObject tokenObject = parseToken(token);
            String userId = tokenObject.get(HeaderNounConstant.USER_ID).toString();
            if(StringUtils.isEmpty(userId)) return "";
            return userId;
        }catch(Exception ex) {
            return "";
        }
    }

    @Override
    public String[] getRoles(String s) {
        // 暂时不用实现，因为不用 JmReport 的角色
        return new String[]{"admin"};
    }

    @Override
    public String getTenantId() {
        try {
            String tenantId = UserUtils.getTenantId();
            if (StringUtils.isEmpty(tenantId)) {
                String token = getToken();
                JSONObject tokenObject = parseToken(token);
                if(Objects.isNull(tokenObject)) return "";
                tenantId =  tokenObject.get(HeaderNounConstant.TENANT_ID).toString();
                if(StringUtils.isEmpty(tenantId)) return "";
            }
            return tenantId;
        }catch(Exception ex) {
            return "";
        }
    }

    /**
     * 解析token
     *
     * @param token token
     * @return
     * @throws ParseException
     */
    private JSONObject parseToken(String token) throws ParseException {
        JSONObject jsonObject = null;
        if (StringUtils.isNotBlank(token)) {
            String payload = JWSObject.parse(token.replace(HeaderNounConstant.JWT_PREFIX, Strings.EMPTY)).getPayload().toString();
            jsonObject = JSONObject.parseObject(payload);
        }
        return jsonObject;
    }
}
